
#include "DupStar.h"
#include "StarMgr.h"
#include "Duplicate/IDuplicate.h"

//////////////////////////////   StarA  ////////////////////////////////////////////

StarA::StarA() :m_pass(false), m_pDuplicate(nullptr), m_idx(-1)
{

}

StarA::~StarA()
{

}

//初始化 1) 通关副本，无参数
bool StarA::init(IDuplicate *pDuplicate, int8_t idx, const VEC_INT32 &vecParam)
{
	if (nullptr == pDuplicate)
	{
		return false;
	}
	MMO_USE_ARGUMENT(vecParam);
	m_pDuplicate = pDuplicate;
	m_idx = idx;
	return true;
}
void StarA::uninit()
{
	m_pDuplicate = nullptr;
	m_idx = -1;
}

//是否完成星级条件
bool StarA::finishStar()
{
	return m_pass;
}

//副本通关
void StarA::pass()
{
	m_pass = true;
	notifyUpdate();
}

void StarA::notifyUpdate()
{
	if (nullptr != m_pDuplicate)
	{
		/*Duplicate_StarStateRsp rsp;
		DupStarStateProto *proto = rsp.add_star_state();
		if (nullptr != proto)
		{
			proto->set_star_idx((int32_t)starIdx());
			proto->set_state((int32_t)finishStar());
		}
		m_pDuplicate->BroadCastData(EMODULE_ID_DUPLICATE, LOGIC_TO_CLIENT_DUPLICATE_STAR_STATE, &rsp);*/
	}
	//LogDebugFmtPrint("[logic] StarA::notifyUpdate....type:%d , state:%d ",starType(),(int32_t)finishStar());
}


//////////////////////////////// StarB //////////////////////////////////////////

StarB::StarB() :m_pDuplicate(nullptr), m_dieNum(0), m_curNum(0), m_idx(-1)
{

}
StarB::~StarB()
{

}
//初始化   2) 死亡次数不超过X次，1个参数（死亡次数）
bool StarB::init(IDuplicate *pDuplicate, int8_t idx, const VEC_INT32 &vecParam)
{
	if (nullptr == pDuplicate)
	{
		return false;
	}
	if (vecParam.size() < 2)
	{
		return false;
	}
	m_dieNum = vecParam.at(1);
	m_pDuplicate = pDuplicate;
	m_idx = idx;
	return true;
}
void StarB::uninit()
{
	m_pDuplicate = nullptr;
	m_dieNum = 0;
	m_curNum = 0;
	m_idx = -1;
}
//是否完成星级条件
bool StarB::finishStar()
{
	return (m_curNum <= m_dieNum);
}
//玩家死亡
void StarB::playerDead()
{
	if (m_curNum >= m_dieNum)
	{
		return;
	}
	m_curNum += 1;
	if (m_curNum >= m_dieNum)
	{
		notifyUpdate();
	}
}
void StarB::notifyUpdate()
{
	if (nullptr != m_pDuplicate)
	{
		/*Duplicate_StarStateRsp rsp;
		DupStarStateProto *proto = rsp.add_star_state();
		if (nullptr != proto)
		{
			proto->set_star_idx((int32_t)starIdx());
			proto->set_state((int32_t)finishStar());
		}
		m_pDuplicate->BroadCastData(EMODULE_ID_DUPLICATE, LOGIC_TO_CLIENT_DUPLICATE_STAR_STATE, &rsp);*/
	}
	//LogDebugFmtPrint("[logic] StarB::notifyUpdate....type:%d , state:%d ", starType(), (int32_t)finishStar());
}

///////////////////////////////// StarC /////////////////////////////////////////

StarC::StarC() :m_pDuplicate(nullptr), m_sec(0), m_pass(false), m_idx(-1)
{

}
StarC::~StarC()
{

}
//初始化 3) X秒内通关，1个参数（通关时间）
bool StarC::init(IDuplicate *pDuplicate, int8_t idx, const VEC_INT32 &vecParam)
{
	if (nullptr == pDuplicate)
	{
		return false;
	}
	if (vecParam.size() < 2)
	{
		return false;
	}
	m_sec = vecParam.at(1);
	m_pDuplicate = pDuplicate;
	m_idx = idx;
	return true;
}
void StarC::uninit()
{
	m_pDuplicate = nullptr;
	m_pass = false;
	m_sec = 0;
	m_idx = -1;
}
//是否完成星级条件
bool StarC::finishStar()
{
	return m_pass;
}
//副本通关
void StarC::pass()
{
	checkPass();
}

void StarC::checkPass()
{
	if (m_pass)
	{
		return;
	}
	uint64_t startTime = m_pDuplicate->StartBrushTime();
	if (startTime > 0) //
	{
		uint64_t curTime = g_GetGlobalServerTime()->UnixSec();
		if (curTime > startTime)
		{
			if (curTime - startTime < (uint64_t)m_sec)
			{
				m_pass = true;
				//更新星级显示
				notifyUpdate();
			}
		}
	}
}

void StarC::notifyUpdate()
{
	if (nullptr != m_pDuplicate)
	{
		/*Duplicate_StarStateRsp rsp;
		DupStarStateProto *proto = rsp.add_star_state();
		if (nullptr != proto)
		{
			proto->set_star_idx((int32_t)starIdx());
			proto->set_state((int32_t)finishStar());
		}
		m_pDuplicate->BroadCastData(EMODULE_ID_DUPLICATE, LOGIC_TO_CLIENT_DUPLICATE_STAR_STATE, &rsp);*/
	}
	//LogDebugFmtPrint("[logic] StarC::notifyUpdate....type:%d , state:%d ", starType(), (int32_t)finishStar());
}

/////////////////////////////////////StarD /////////////////////////////////////

StarD::StarD() :m_pDuplicate(nullptr), m_dstMonsId(0), m_dstNum(0), m_num(0), m_idx(-1)
{

}
StarD::~StarD()
{

}
//初始化 4) 消灭X个怪物Y，2个参数(X为怪物数量，Y为怪物ID)
bool StarD::init(IDuplicate *pDuplicate, int8_t idx, const VEC_INT32 &vecParam)
{
	if (nullptr == pDuplicate)
	{
		return false;
	}
	if (vecParam.size() < 3)
	{
		return false;
	}
	m_dstNum = vecParam.at(1);
	m_dstMonsId = vecParam.at(2);
	m_pDuplicate = pDuplicate;
	m_idx = idx;
	return true;
}
void StarD::uninit()
{
	m_dstNum = 0;
	m_dstMonsId = 0;
	m_pDuplicate = nullptr;
	m_num = 0;
	m_idx = -1;
}
//是否完成星级条件
bool StarD::finishStar()
{
	return (m_num >= m_dstNum);
}
//怪物死亡
void StarD::monsDead(uint32_t monsId, uint32_t monsNum, int32_t parentType)
{
	_UNUSE(parentType);
	if (m_num >= m_dstNum || m_dstMonsId != monsId)
	{
		return;
	}
	m_num += monsNum;
	if (m_num >= m_dstNum)
	{
		//星级条件达成
		notifyUpdate();

	}
}

void StarD::notifyUpdate()
{
	if (nullptr != m_pDuplicate)
	{
		/*Duplicate_StarStateRsp rsp;
		DupStarStateProto *proto = rsp.add_star_state();
		if (nullptr != proto)
		{
			proto->set_star_idx((int32_t)starIdx());
			proto->set_state((int32_t)finishStar());
		}
		m_pDuplicate->BroadCastData(EMODULE_ID_DUPLICATE, LOGIC_TO_CLIENT_DUPLICATE_STAR_STATE, &rsp);*/
	}
	//LogDebugFmtPrint("[logic] StarD::notifyUpdate....type:%d , state:%d ", starType(), (int32_t)finishStar());
}


/////////////////////////////////// StarE ///////////////////////////////////////

StarE::StarE() :m_pDuplicate(nullptr), m_num(0), m_dstNum(0), m_idx(-1)
{
	m_setFilterType.clear();
}
StarE::~StarE()
{

}
//5) 消灭X个怪物（表示副本内的所有ID类型怪物）
//一般至少2个参数（怪物数量、怪物类型序列【用分号隔开】）
//如果只写消灭怪物数量（参数1），不写怪物类型序列（参数2及后续），表示是所有怪物类型
bool StarE::init(IDuplicate *pDuplicate, int8_t idx, const VEC_INT32 &vecParam)
{
	if (nullptr == pDuplicate)
	{
		return false;
	}
	int32_t isize = vecParam.size();
	if (isize < 2)
	{
		return false;
	}
	//目标数量
	m_dstNum = vecParam.at(1);
	//
	for (int32_t i = 2; i < isize; ++i)
	{
		if (vecParam.at(i) > 0)
		{
			m_setFilterType.insert(vecParam.at(i));
		}
	}

	m_pDuplicate = pDuplicate;
	m_idx = idx;
	return true;
}
void StarE::uninit()
{
	m_pDuplicate = nullptr;
	m_dstNum = 0;
	m_num = 0;
	m_idx = -1;
	m_setFilterType.clear();
}
//是否完成星级条件
bool StarE::finishStar()
{
	return (m_num >= m_dstNum);
}
//怪物死亡
void StarE::monsDead(uint32_t monsId, uint32_t monsNum, int32_t parentType)
{
	MMO_USE_ARGUMENT(monsId);
	if (m_num >= m_dstNum)
	{
		return;
	}
	bool flag = true;
	if (m_setFilterType.size() > 0)
	{
		//需要过滤类型
		SET_INT32::iterator iter = m_setFilterType.find(parentType);
		if (iter == m_setFilterType.end())
		{
			flag = false;
		}
	}
	if (flag)
	{
		m_num += monsNum;
		if (m_num >= m_dstNum)
		{
			//星级达成
			notifyUpdate();
		}
	}
}

void StarE::notifyUpdate()
{
	if (nullptr != m_pDuplicate)
	{
		/*Duplicate_StarStateRsp rsp;
		DupStarStateProto *proto = rsp.add_star_state();
		if (nullptr != proto)
		{
			proto->set_star_idx((int32_t)starIdx());
			proto->set_state((int32_t)finishStar());
		}
		m_pDuplicate->BroadCastData(EMODULE_ID_DUPLICATE, LOGIC_TO_CLIENT_DUPLICATE_STAR_STATE, &rsp);*/
	}
	//LogDebugFmtPrint("[logic] StarE::notifyUpdate....type:%d , state:%d ", starType(), (int32_t)finishStar());
}









/////////////////////////////// DupStar ///////////////////////////////////////////


DupStar::DupStar()
{
	m_mapStar.clear();
}

DupStar::~DupStar()
{

}

//初始化
bool DupStar::init(IDuplicate *pDuplicate, const VEC_VEC_INT32 *pStarCfg)
{
	if (nullptr == pStarCfg)
	{
		return false;
	}
	int32_t isize = pStarCfg->size();
	for (int32_t i = 0; i < isize; ++i)
	{
		const VEC_INT32 &param = pStarCfg->at(i);
		if (param.size() < 1)
		{
			uninit();
			return false;
		}
		int8_t itype = (int8_t)param.at(0);
		IStar *pStar = g_GetStarMgr()->MakeStarObj(itype);
		if (nullptr == pStar)
		{
			uninit();
			return false;
		}
		if (!pStar->init(pDuplicate,i, param))
		{
			g_GetStarMgr()->FreeStarObj(pStar);
			uninit();
			return false;
		}
		m_mapStar[pStar->starIdx()] = pStar;
	}

	return true;
}

void DupStar::uninit()
{
	DupStarMap::iterator iter = m_mapStar.begin();
	for (; iter != m_mapStar.end(); ++iter)
	{
		IStar *pstar = iter->second;
		if (nullptr != pstar)
		{
			g_GetStarMgr()->RecycleStar(pstar);
		}
	}
	m_mapStar.clear();
}

//副本通关
void DupStar::pass()
{
	DupStarMap::iterator iter = m_mapStar.begin();
	for (; iter != m_mapStar.end(); ++iter)
	{
		IStar *pstar = iter->second;
		if (nullptr != pstar)
		{
			pstar->pass();
		}
	}
}
//怪物死亡
void DupStar::monsDead(uint32_t monsId, uint32_t monsNum,int32_t parentType)
{
	DupStarMap::iterator iter = m_mapStar.begin();
	for (; iter != m_mapStar.end(); ++iter)
	{
		IStar *pstar = iter->second;
		if (nullptr != pstar)
		{
			pstar->monsDead(monsId, monsNum, parentType);
		}
	}
}
//玩家死亡
void DupStar::playerDead()
{
	DupStarMap::iterator iter = m_mapStar.begin();
	for (; iter != m_mapStar.end(); ++iter)
	{
		IStar *pstar = iter->second;
		if (nullptr != pstar)
		{
			pstar->playerDead();
		}
	}
}


//获取所有星级状态
int8_t DupStar::getStarState(MAP_INT8_INT8 &mapState)
{
	int8_t star = 0;
	DupStarMap::iterator iter = m_mapStar.begin();
	for (; iter != m_mapStar.end(); ++iter)
	{
		IStar *pstar = iter->second;
		if (nullptr != pstar)
		{
			mapState[pstar->starIdx()] = (int8_t)pstar->finishStar();
			if (pstar->finishStar())
			{
				star += 1;
			}
		}
	}
	return star;
}